/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package graphics;

import forhelp.PrintArray;
import graphics.support.ChildrenGraphActionListener;
import myarrays.MyArrays;
import graphics.support.MyEvent;
import graphics.support.RainBowPaintScale;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.util.ArrayList;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import opener.*;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.panel.CrosshairOverlay;
import org.jfree.chart.plot.Crosshair;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.PaintScale;
import org.jfree.chart.renderer.xy.XYBlockRenderer;

/**
 *
 * @author Denisov Sergey
 */
public class Maingraph extends javax.swing.JFrame {

    private double[][] data;
    private double[] dataSpectra;
    private double[][] workingarea = new double[2][2];
    private double[] AtimeDelays;
    private double[] AwaveLength;
    private double max_wavelength;
    private double min_wavelength;
    private double max_timedelay;
    private double min_timedelay;
    private double maxData;
    private double minData;
    private String typeYaxis;
    private String typeFile;

    private ChartPanel MainChartPanel;

    private JFreeChart MainChart;

    private XYPlot MainPlot;
    private PaintScale Mainscale;
    private XYBlockRenderer MainRenderer;
    private Crosshair MainCrosshair1X;
    private Crosshair MainCrosshair1Y;
    private Crosshair MainCrosshair2X;
    private Crosshair MainCrosshair2Y;
    private CrosshairOverlay MainOverlay;
    private final int width = 800;
    private final int height = 600;

    private Spectragraph SpectraGraph;
    private Kineticsgraph KineticsGraph;
    private ChildrenGraphActionListener listenerSpectra = new ChildrenGraphActionListener();
    private ChildrenGraphActionListener listenerKinetics = new ChildrenGraphActionListener();

    /**
     * Creates new form Maingraph
     *
     * @param data
     * @param AtimeDelays
     * @param AwaveLength
     * @param timedelays
     * @param typeFile
     * @param wavelength
     */
    public Maingraph(double[][] data, double[] AtimeDelays, double[] AwaveLength, String typeFile) {
        initComponents();
        myinit(data, AtimeDelays, AwaveLength, typeFile);
    }

    private void myinit(double[][] data, double[] AtimeDelays, double[] AwaveLength, String typeFile) {

        this.data = data;
        this.typeFile = typeFile;
        if ("femto".equals(this.typeFile)) {
            this.typeYaxis = "numbers";

        } else {
            this.typeYaxis = "real";
        }

        this.AtimeDelays = AtimeDelays;
        this.AwaveLength = AwaveLength;
        this.max_timedelay = AtimeDelays.length - 1;
        this.min_timedelay = 0;
        this.max_wavelength = AwaveLength[AwaveLength.length - 1];
        this.min_wavelength = AwaveLength[0];
        this.maxData = MyArrays.FindMax(data);
        this.minData = MyArrays.FindMin(data);

        MainOverlay = new CrosshairOverlay();
        this.MainCrosshair1X = new Crosshair((this.max_wavelength + this.min_wavelength) * 0.8 / 2, Color.BLACK, new BasicStroke(2));
        this.MainCrosshair1Y = new Crosshair(this.max_timedelay * 0.8 / 2, Color.BLACK, new BasicStroke(2));
        this.MainCrosshair2X = new Crosshair((this.max_wavelength + this.min_wavelength) * 1.2 / 2, Color.RED, new BasicStroke(2));
        this.MainCrosshair2Y = new Crosshair(this.max_timedelay * 1.2 / 2, Color.RED, new BasicStroke(2));

        workingarea[0][0] = this.MainCrosshair1X.getValue();
        workingarea[0][1] = this.MainCrosshair2X.getValue();
        workingarea[1][0] = this.MainCrosshair1Y.getValue();
        workingarea[1][1] = this.MainCrosshair2Y.getValue();

        MainOverlay.addDomainCrosshair(MainCrosshair1X);
        MainOverlay.addDomainCrosshair(MainCrosshair2X);
        MainOverlay.addRangeCrosshair(MainCrosshair1Y);
        MainOverlay.addRangeCrosshair(MainCrosshair2Y);

        rangeSlider.setPreferredSize(new Dimension(50, rangeSlider.getPreferredSize().height));
        rangeSlider.setMinimum(0);
        rangeSlider.setMaximum(100);
        rangeSlider.setValue(10);
        rangeSlider.setUpperValue(90);
        rangeSlider.setOrientation(javax.swing.JSlider.VERTICAL);

        rangeSlider.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                Mainscale = new RainBowPaintScale(minData - minData * (rangeSlider.getValue()) / 50, maxData - maxData * (100 - rangeSlider.getUpperValue()) / 50, Color.black);
                MainRenderer.setPaintScale(Mainscale);
            }
        });

        MainChartPanel = new ChartPanel(createXYZChart(), width, height, 16, 16, width * 10, height * 10, true, true, true, true, true, true, true);

        MainChartPanel.setFocusable(rootPaneCheckingEnabled);
        MainChartPanel.setDomainZoomable(true);

        MainChartPanel.addOverlay(MainOverlay);
        listenerSpectra.setButton(SpectraButton);
        SpectraGraph = new Spectragraph(data, AwaveLength, AtimeDelays, workingarea, max_wavelength, min_wavelength, typeYaxis, listenerSpectra);
        SpectraGraph.setVisible(false);
        listenerKinetics.setButton(KineticsButton);
        KineticsGraph = new Kineticsgraph(data, AwaveLength, AtimeDelays, workingarea, max_timedelay, min_timedelay, typeYaxis, listenerKinetics);
        KineticsGraph.setVisible(false);

        MyEvent mylistener = new MyEvent(this);

        MainChartPanel.addMouseListener(mylistener);
        MainChartPanel.addMouseMotionListener(mylistener);
        this.setFocusable(true);
        this.addKeyListener(mylistener);

        PanelMainChartConteiner.add(MainChartPanel);
        this.pack();
    }

    private JFreeChart createXYZChart() {
        NumberAxis xAxis = new NumberAxis("Wavelength, nm");
        xAxis.setRange(min_wavelength, max_wavelength);
        xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        xAxis.setFixedAutoRange(max_wavelength - min_wavelength);

        NumberAxis yAxis = new NumberAxis("# of spectrum");
        yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        yAxis.setLowerMargin(0.0);
        yAxis.setUpperMargin(0.0);
        MainRenderer = new XYBlockRenderer();

        Mainscale = new RainBowPaintScale(minData - minData * (rangeSlider.getValue()) / 50, maxData - maxData * (100 - rangeSlider.getUpperValue()) / 50, Color.BLACK);
        MainRenderer.setPaintScale(Mainscale);
        XYZArrayDataset dataset = new XYZArrayDataset(data, AtimeDelays, AwaveLength);
        MainPlot = new XYPlot(dataset, xAxis, yAxis, MainRenderer);
        MainPlot.setBackgroundPaint(Color.lightGray);
        MainPlot.setDomainGridlinesVisible(false);
        MainPlot.setRangeGridlinePaint(Color.white);
        MainChart = new JFreeChart("MAINGRAPH", MainPlot);
        MainChart.removeLegend();
        MainChart.setBackgroundPaint(Color.white);
        return MainChart;
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jpanel0 = new javax.swing.JPanel();
        PanelMainChartConteiner = new javax.swing.JPanel();
        filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 0), new java.awt.Dimension(0, 0), new java.awt.Dimension(32767, 0));
        SpectraButton = new javax.swing.JToggleButton();
        KineticsButton = new javax.swing.JToggleButton();
        rangeSlider = new graphics.Slider.RangeSlider();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setBackground(new java.awt.Color(255, 51, 51));

        jpanel0.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        PanelMainChartConteiner.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        PanelMainChartConteiner.setLayout(new java.awt.BorderLayout());

        SpectraButton.setText("Spectra");
        SpectraButton.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                SpectraButtonItemStateChanged(evt);
            }
        });

        KineticsButton.setText("Kinetics");
        KineticsButton.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                KineticsButtonItemStateChanged(evt);
            }
        });

        javax.swing.GroupLayout jpanel0Layout = new javax.swing.GroupLayout(jpanel0);
        jpanel0.setLayout(jpanel0Layout);
        jpanel0Layout.setHorizontalGroup(
            jpanel0Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jpanel0Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jpanel0Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jpanel0Layout.createSequentialGroup()
                        .addComponent(SpectraButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(KineticsButton)
                        .addGap(0, 579, Short.MAX_VALUE))
                    .addComponent(PanelMainChartConteiner, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        jpanel0Layout.setVerticalGroup(
            jpanel0Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jpanel0Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jpanel0Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(PanelMainChartConteiner, javax.swing.GroupLayout.PREFERRED_SIZE, 544, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(filler1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE)
                .addGroup(jpanel0Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(SpectraButton)
                    .addComponent(KineticsButton))
                .addContainerGap())
        );

        rangeSlider.setOrientation(javax.swing.JSlider.VERTICAL);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(25, 25, 25)
                .addComponent(rangeSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jpanel0, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(rangeSlider, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jpanel0, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void SpectraButtonItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_SpectraButtonItemStateChanged
        if (evt.getStateChange() == ItemEvent.SELECTED) {
            SpectraButton.setText("Spectra-On");
            SpectraGraph.setVisible(true);

        } else {
            SpectraButton.setText("Spectra-Off");
            SpectraGraph.setVisible(false);
        }
    }//GEN-LAST:event_SpectraButtonItemStateChanged

    private void KineticsButtonItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_KineticsButtonItemStateChanged
        if (evt.getStateChange() == ItemEvent.SELECTED) {
            KineticsButton.setText("Kinetics-On");
            KineticsGraph.setVisible(true);
        } else {
            KineticsButton.setText("Kinetics-Off");
            KineticsGraph.setVisible(false);
        }
    }//GEN-LAST:event_KineticsButtonItemStateChanged

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JToggleButton KineticsButton;
    private javax.swing.JPanel PanelMainChartConteiner;
    private javax.swing.JToggleButton SpectraButton;
    private javax.swing.Box.Filler filler1;
    private javax.swing.JPanel jpanel0;
    private graphics.Slider.RangeSlider rangeSlider;
    // End of variables declaration//GEN-END:variables
    public double getMaxWavelength() {
        return this.max_wavelength;
    }

    public double getMinWavelength() {
        return this.min_wavelength;
    }

    public double getMaxTimedelay() {
        return this.max_timedelay;
    }

    public double getMinTimedelay() {
        return this.min_timedelay;
    }

    public double[][] getWorkingArea() {
        return this.workingarea;
    }

    public void setWorkingArea(double[][] var) {
        this.workingarea = var;
    }

    public JFreeChart getJFreeChart() {
        return this.MainChart;
    }

    public ChartPanel getChartPanel() {
        return MainChartPanel;
    }

    public void setChartPanel(ChartPanel chartPanel) {
        this.MainChartPanel = chartPanel;
    }

    public ArrayList<Crosshair> getCrossHairs() {
        ArrayList<Crosshair> var = new ArrayList<>();
        var.add(this.MainCrosshair1X);
        var.add(this.MainCrosshair1Y);
        var.add(this.MainCrosshair2X);
        var.add(this.MainCrosshair2Y);
        return var;
    }

    public void setCrossHair(Crosshair A, String Name) {
        if ("1X".equals(Name)) {
            this.MainCrosshair1X.setValue(A.getValue());
        }
        if ("1Y".equals(Name)) {
            this.MainCrosshair1Y.setValue(A.getValue());
        }

        if ("2X".equals(Name)) {
            this.MainCrosshair2X.setValue(A.getValue());
        }

        if ("2Y".equals(Name)) {
            this.MainCrosshair2Y.setValue(A.getValue());
        }
    }

    public void setOverlay(CrosshairOverlay overlay) {
        this.MainOverlay = overlay;
    }

    public CrosshairOverlay getOverlay() {
        return this.MainOverlay;
    }

    public XYPlot getPlot() {
        return this.MainPlot;
    }

    public void setPlot(XYPlot plot) {
        this.MainPlot = plot;
    }

    public XYBlockRenderer getRenderer() {
        return this.MainRenderer;
    }

    public void setRenderer(XYBlockRenderer renderer) {
        this.MainRenderer = renderer;
    }

    public Spectragraph getSpectraGraph() {
        return SpectraGraph;
    }

    public Kineticsgraph getKineticsGraph() {
        return KineticsGraph;
    }

    public void setSpectragraph(Boolean var) {
        SpectraButton.setVisible(var);
    }
}
